Validate value from GDK settings against parameter spec.
authorOwen Taylor <otaylor@redhat.com>
Wed, 30 May 2001 20:40:28 +0000 (20:40 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Wed, 30 May 2001 20:40:28 +0000 (20:40 +0000)
Wed May 30 15:56:30 2001  Owen Taylor  <otaylor@redhat.com>

* gtk/gtksettings.c (gtk_settings_get_property): Validate
value from GDK settings against parameter spec.

* gdk/x11/gdkevents-x11.c (gdk_setting_get): Add assignments
to temporary values and use g_value_transform(), since
thinking that GValue was going to be easy or efficient
to use was, of course, a mistake.

        * gtk/gtksettings.c: Add cursor blink setting.

* gdk/x11/gdkevents-x11.c: Add cursor blink X settings.

* gtk/gtkentry.c: Add cursor blinking.

* gtk/gtktextview.c (gtk_text_view_check_cursor_blink): Use
cursor blink global settings.

* gtk/gtkentry.c (gtk_entry_button_press): Add notification
for :text_position in places where it is missing.

14 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/reference/gtk/tmpl/gtkrc.sgml
gdk/x11/gdkevents-x11.c
gtk/gtkentry.c
gtk/gtkentry.h
gtk/gtksettings.c
gtk/gtktextview.c
gtk/gtktextview.h

index c550469f88a6c25409cdccea8cb95feece976036..5dfba01085ef0172eccf435c9792162f6095d83d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+Wed May 30 15:56:30 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksettings.c (gtk_settings_get_property): Validate
+       value from GDK settings against parameter spec.
+
+       * gdk/x11/gdkevents-x11.c (gdk_setting_get): Add assignments
+       to temporary values and use g_value_transform(), since
+       thinking that GValue was going to be easy or efficient
+       to use was, of course, a mistake.
+
+        * gtk/gtksettings.c: Add cursor blink setting.
+       
+       * gdk/x11/gdkevents-x11.c: Add cursor blink X settings.
+
+       * gtk/gtkentry.c: Add cursor blinking.
+
+       * gtk/gtktextview.c (gtk_text_view_check_cursor_blink): Use
+       cursor blink global settings.
+
+       * gtk/gtkentry.c (gtk_entry_button_press): Add notification
+       for :text_position in places where it is missing.
+
 Tue May 29 18:17:11 2001  Owen Taylor  <otaylor@redhat.com>
 
        * autogen.sh (have_libtool): Fix GNU sedism (#55430)
index c550469f88a6c25409cdccea8cb95feece976036..5dfba01085ef0172eccf435c9792162f6095d83d 100644 (file)
@@ -1,3 +1,25 @@
+Wed May 30 15:56:30 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksettings.c (gtk_settings_get_property): Validate
+       value from GDK settings against parameter spec.
+
+       * gdk/x11/gdkevents-x11.c (gdk_setting_get): Add assignments
+       to temporary values and use g_value_transform(), since
+       thinking that GValue was going to be easy or efficient
+       to use was, of course, a mistake.
+
+        * gtk/gtksettings.c: Add cursor blink setting.
+       
+       * gdk/x11/gdkevents-x11.c: Add cursor blink X settings.
+
+       * gtk/gtkentry.c: Add cursor blinking.
+
+       * gtk/gtktextview.c (gtk_text_view_check_cursor_blink): Use
+       cursor blink global settings.
+
+       * gtk/gtkentry.c (gtk_entry_button_press): Add notification
+       for :text_position in places where it is missing.
+
 Tue May 29 18:17:11 2001  Owen Taylor  <otaylor@redhat.com>
 
        * autogen.sh (have_libtool): Fix GNU sedism (#55430)
index c550469f88a6c25409cdccea8cb95feece976036..5dfba01085ef0172eccf435c9792162f6095d83d 100644 (file)
@@ -1,3 +1,25 @@
+Wed May 30 15:56:30 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksettings.c (gtk_settings_get_property): Validate
+       value from GDK settings against parameter spec.
+
+       * gdk/x11/gdkevents-x11.c (gdk_setting_get): Add assignments
+       to temporary values and use g_value_transform(), since
+       thinking that GValue was going to be easy or efficient
+       to use was, of course, a mistake.
+
+        * gtk/gtksettings.c: Add cursor blink setting.
+       
+       * gdk/x11/gdkevents-x11.c: Add cursor blink X settings.
+
+       * gtk/gtkentry.c: Add cursor blinking.
+
+       * gtk/gtktextview.c (gtk_text_view_check_cursor_blink): Use
+       cursor blink global settings.
+
+       * gtk/gtkentry.c (gtk_entry_button_press): Add notification
+       for :text_position in places where it is missing.
+
 Tue May 29 18:17:11 2001  Owen Taylor  <otaylor@redhat.com>
 
        * autogen.sh (have_libtool): Fix GNU sedism (#55430)
index c550469f88a6c25409cdccea8cb95feece976036..5dfba01085ef0172eccf435c9792162f6095d83d 100644 (file)
@@ -1,3 +1,25 @@
+Wed May 30 15:56:30 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksettings.c (gtk_settings_get_property): Validate
+       value from GDK settings against parameter spec.
+
+       * gdk/x11/gdkevents-x11.c (gdk_setting_get): Add assignments
+       to temporary values and use g_value_transform(), since
+       thinking that GValue was going to be easy or efficient
+       to use was, of course, a mistake.
+
+        * gtk/gtksettings.c: Add cursor blink setting.
+       
+       * gdk/x11/gdkevents-x11.c: Add cursor blink X settings.
+
+       * gtk/gtkentry.c: Add cursor blinking.
+
+       * gtk/gtktextview.c (gtk_text_view_check_cursor_blink): Use
+       cursor blink global settings.
+
+       * gtk/gtkentry.c (gtk_entry_button_press): Add notification
+       for :text_position in places where it is missing.
+
 Tue May 29 18:17:11 2001  Owen Taylor  <otaylor@redhat.com>
 
        * autogen.sh (have_libtool): Fix GNU sedism (#55430)
index c550469f88a6c25409cdccea8cb95feece976036..5dfba01085ef0172eccf435c9792162f6095d83d 100644 (file)
@@ -1,3 +1,25 @@
+Wed May 30 15:56:30 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksettings.c (gtk_settings_get_property): Validate
+       value from GDK settings against parameter spec.
+
+       * gdk/x11/gdkevents-x11.c (gdk_setting_get): Add assignments
+       to temporary values and use g_value_transform(), since
+       thinking that GValue was going to be easy or efficient
+       to use was, of course, a mistake.
+
+        * gtk/gtksettings.c: Add cursor blink setting.
+       
+       * gdk/x11/gdkevents-x11.c: Add cursor blink X settings.
+
+       * gtk/gtkentry.c: Add cursor blinking.
+
+       * gtk/gtktextview.c (gtk_text_view_check_cursor_blink): Use
+       cursor blink global settings.
+
+       * gtk/gtkentry.c (gtk_entry_button_press): Add notification
+       for :text_position in places where it is missing.
+
 Tue May 29 18:17:11 2001  Owen Taylor  <otaylor@redhat.com>
 
        * autogen.sh (have_libtool): Fix GNU sedism (#55430)
index c550469f88a6c25409cdccea8cb95feece976036..5dfba01085ef0172eccf435c9792162f6095d83d 100644 (file)
@@ -1,3 +1,25 @@
+Wed May 30 15:56:30 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksettings.c (gtk_settings_get_property): Validate
+       value from GDK settings against parameter spec.
+
+       * gdk/x11/gdkevents-x11.c (gdk_setting_get): Add assignments
+       to temporary values and use g_value_transform(), since
+       thinking that GValue was going to be easy or efficient
+       to use was, of course, a mistake.
+
+        * gtk/gtksettings.c: Add cursor blink setting.
+       
+       * gdk/x11/gdkevents-x11.c: Add cursor blink X settings.
+
+       * gtk/gtkentry.c: Add cursor blinking.
+
+       * gtk/gtktextview.c (gtk_text_view_check_cursor_blink): Use
+       cursor blink global settings.
+
+       * gtk/gtkentry.c (gtk_entry_button_press): Add notification
+       for :text_position in places where it is missing.
+
 Tue May 29 18:17:11 2001  Owen Taylor  <otaylor@redhat.com>
 
        * autogen.sh (have_libtool): Fix GNU sedism (#55430)
index c550469f88a6c25409cdccea8cb95feece976036..5dfba01085ef0172eccf435c9792162f6095d83d 100644 (file)
@@ -1,3 +1,25 @@
+Wed May 30 15:56:30 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtksettings.c (gtk_settings_get_property): Validate
+       value from GDK settings against parameter spec.
+
+       * gdk/x11/gdkevents-x11.c (gdk_setting_get): Add assignments
+       to temporary values and use g_value_transform(), since
+       thinking that GValue was going to be easy or efficient
+       to use was, of course, a mistake.
+
+        * gtk/gtksettings.c: Add cursor blink setting.
+       
+       * gdk/x11/gdkevents-x11.c: Add cursor blink X settings.
+
+       * gtk/gtkentry.c: Add cursor blinking.
+
+       * gtk/gtktextview.c (gtk_text_view_check_cursor_blink): Use
+       cursor blink global settings.
+
+       * gtk/gtkentry.c (gtk_entry_button_press): Add notification
+       for :text_position in places where it is missing.
+
 Tue May 29 18:17:11 2001  Owen Taylor  <otaylor@redhat.com>
 
        * autogen.sh (have_libtool): Fix GNU sedism (#55430)
index 88a0a4a50768b9125a3501db571c351823709144..aeceb3e5ec5128ed4fb5e158a0cdbac4c0421aeb 100644 (file)
@@ -495,7 +495,6 @@ This can later be composited together with other
 #GtkRcStyle structures to form a #GtkStyle.
 </para>
 
-@parent_instance: 
 @name: 
 @bg_pixmap_name: 
 @font_desc: 
index 2655d4278f7bd4caa3483f0f6b01796e0658e40e..ab931ad82e5b5ac5dfd38a8342131eb0a8e52ae2 100644 (file)
@@ -1912,7 +1912,9 @@ static struct
   const char *gdk_name;
 } settings_map[] = {
   { "Net/DoubleClickTime", "gtk-double-click-timeout" },
-  { "Net/DragThreshold", "gtk-drag-threshold" }
+  { "Net/DragThreshold", "gtk-drag-threshold" },
+  { "Net/CursorBlink", "gtk-cursor-blink" },
+  { "Net/CursorBlinkTime", "gtk-cursor-blink-time" }
 };
 
 static void
@@ -1981,6 +1983,7 @@ gdk_setting_get (const gchar *name,
   XSettingsSetting *setting;
   gboolean success = FALSE;
   gint i;
+  GValue tmp_val = { 0, };
 
   for (i = 0; i < G_N_ELEMENTS (settings_map) ; i++)
     if (strcmp (settings_map[i].gdk_name, name) == 0)
@@ -2001,14 +2004,20 @@ gdk_setting_get (const gchar *name,
     case XSETTINGS_TYPE_INT:
       if (check_transform (xsettings_name, G_TYPE_INT, G_VALUE_TYPE (value)))
        {
-         g_value_set_int (value, setting->data.v_int);
+         g_value_init (&tmp_val, G_TYPE_INT);
+         g_value_set_int (&tmp_val, setting->data.v_int);
+         g_value_transform (&tmp_val, value);
+
          success = TRUE;
        }
       break;
     case XSETTINGS_TYPE_STRING:
       if (check_transform (xsettings_name, G_TYPE_STRING, G_VALUE_TYPE (value)))
        {
-         g_value_set_string (value, setting->data.v_string);
+         g_value_init (&tmp_val, G_TYPE_STRING);
+         g_value_set_string (&tmp_val, setting->data.v_string);
+         g_value_transform (&tmp_val, value);
+
          success = TRUE;
        }
       break;
@@ -2017,17 +2026,23 @@ gdk_setting_get (const gchar *name,
        {
          GdkColor color;
          
+         g_value_init (&tmp_val, GDK_TYPE_COLOR);
+
          color.pixel = 0;
          color.red = setting->data.v_color.red;
          color.green = setting->data.v_color.green;
          color.blue = setting->data.v_color.blue;
          
-         g_value_set_boxed (value, &color);
+         g_value_set_boxed (&tmp_val, &color);
+         
+         g_value_transform (&tmp_val, value);
          
          success = TRUE;
        }
       break;
     }
+  
+  g_value_unset (&tmp_val);
 
   xsettings_setting_free (setting);
 
index ccb21525b4f527c78ec779d88989307f0ae8216c..098b6b9ca5232b0719188e9b4ccaaf04171ffe2f 100644 (file)
@@ -40,6 +40,7 @@
 #include "gtkmenuitem.h"
 #include "gtkseparatormenuitem.h"
 #include "gtkselection.h"
+#include "gtksettings.h"
 #include "gtksignal.h"
 #include "gtkwindow.h"
 
@@ -219,6 +220,9 @@ static void gtk_entry_preedit_changed_cb  (GtkIMContext      *context,
                                           GtkEntry          *entry);
 /* Internal routines
  */
+static void         gtk_entry_set_positions            (GtkEntry       *entry,
+                                                       gint            current_pos,
+                                                       gint            selection_bound);
 static void         gtk_entry_draw_text                (GtkEntry       *entry);
 static void         gtk_entry_draw_cursor              (GtkEntry       *entry,
                                                        CursorType      type);
@@ -257,6 +261,8 @@ static void         gtk_entry_do_popup                 (GtkEntry       *entry,
                                                        GdkEventButton *event);
 static gboolean     gtk_entry_mnemonic_activate        (GtkWidget      *widget,
                                                        gboolean        group_cycling);
+static void         gtk_entry_check_cursor_blink       (GtkEntry       *entry);
+static void         gtk_entry_pend_cursor_blink        (GtkEntry       *entry);
 
 static GtkWidgetClass *parent_class = NULL;
 
@@ -861,8 +867,8 @@ gtk_entry_finalize (GObject *object)
 
   gtk_object_unref (GTK_OBJECT (entry->im_context));
 
-  if (entry->timer)
-    g_source_remove (entry->timer);
+  if (entry->blink_timeout)
+    g_source_remove (entry->blink_timeout);
 
   if (entry->recompute_idle)
     g_source_remove (entry->recompute_idle);
@@ -1250,7 +1256,7 @@ gtk_entry_expose (GtkWidget      *widget,
 
       if ((entry->visible || entry->invisible_char != 0) &&
          GTK_WIDGET_HAS_FOCUS (widget) &&
-         entry->selection_bound == entry->current_pos)
+         entry->selection_bound == entry->current_pos && entry->cursor_visible)
        gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_STANDARD);
 
       if (entry->dnd_position != -1)
@@ -1289,13 +1295,15 @@ gtk_entry_button_press (GtkWidget      *widget,
       
       if (event->state & GDK_SHIFT_MASK)
        {
+         gtk_entry_reset_im_context (entry);
+         
          if (!have_selection) /* select from the current position to the clicked position */
            sel_start = sel_end = entry->current_pos;
          
          if (tmp_pos > sel_start && tmp_pos < sel_end)
            {
              /* Truncate current selection */
-             entry->current_pos = tmp_pos;
+             gtk_entry_set_positions (entry, tmp_pos, -1);
            }
          else
            {
@@ -1306,7 +1314,7 @@ gtk_entry_button_press (GtkWidget      *widget,
              switch (event->type)
                {
                case GDK_BUTTON_PRESS:
-                 entry->current_pos = entry->selection_bound = tmp_pos;
+                 gtk_entry_set_positions (entry, tmp_pos, tmp_pos);
                  break;
                  
                case GDK_2BUTTON_PRESS:
@@ -1333,18 +1341,10 @@ gtk_entry_button_press (GtkWidget      *widget,
                extend_to_left = (end == sel_end);
              
              if (extend_to_left)
-               {
-                 entry->selection_bound = end;
-                 entry->current_pos = start;
-               }
+               gtk_entry_set_positions (entry, start, end);
              else
-               {
-                 entry->selection_bound = start;
-                 entry->current_pos = end;
-               }
+               gtk_entry_set_positions (entry, end, start);
            }
-         
-         gtk_entry_recompute (entry);
        }
       else /* no shift key */
        switch (event->type)
@@ -1361,14 +1361,7 @@ gtk_entry_button_press (GtkWidget      *widget,
              entry->drag_start_y = event->y + entry->scroll_offset;
            }
          else
-           {
-             gtk_entry_reset_im_context (entry);
-             
-             entry->current_pos = tmp_pos;
-             entry->selection_bound = tmp_pos;
-
-             gtk_entry_recompute (entry);
-           }
+           gtk_editable_set_position (editable, tmp_pos);
          
          break;
 
@@ -1428,12 +1421,7 @@ gtk_entry_button_release (GtkWidget      *widget,
     {
       gint tmp_pos = gtk_entry_find_position (entry, entry->drag_start_x);
 
-      gtk_entry_reset_im_context (entry);
-             
-      entry->current_pos = tmp_pos;
-      entry->selection_bound = tmp_pos;
-             
-      gtk_entry_recompute (entry);
+      gtk_editable_set_position (GTK_EDITABLE (entry), tmp_pos);
 
       entry->in_drag = 0;
     }
@@ -1481,12 +1469,7 @@ gtk_entry_motion_notify (GtkWidget      *widget,
   else
     {
       tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset);
-
-      if (tmp_pos != entry->current_pos)
-       {
-         entry->current_pos = tmp_pos;
-         gtk_entry_recompute (entry);
-       }
+      gtk_entry_set_positions (entry, tmp_pos, -1);
     }
       
   return TRUE;
@@ -1501,6 +1484,8 @@ gtk_entry_key_press (GtkWidget   *widget,
   if (!entry->editable)
     return FALSE;
 
+  gtk_entry_pend_cursor_blink (entry);
+  
   if (gtk_im_context_filter_keypress (entry->im_context, event))
     {
       entry->need_im_reset = TRUE;
@@ -1518,17 +1503,16 @@ static gint
 gtk_entry_focus_in (GtkWidget     *widget,
                    GdkEventFocus *event)
 {
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
+  GtkEntry *entry = GTK_ENTRY (widget);
+  
   GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
-  gtk_entry_draw_focus (widget);
-  gtk_entry_queue_draw (GTK_ENTRY (widget));
+  gtk_entry_queue_draw (entry);
   
-  GTK_ENTRY (widget)->need_im_reset = TRUE;
-  gtk_im_context_focus_in (GTK_ENTRY (widget)->im_context);
+  entry->need_im_reset = TRUE;
+  gtk_im_context_focus_in (entry->im_context);
 
+  gtk_entry_check_cursor_blink (entry);
+  
   return FALSE;
 }
 
@@ -1536,17 +1520,16 @@ static gint
 gtk_entry_focus_out (GtkWidget     *widget,
                     GdkEventFocus *event)
 {
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-
+  GtkEntry *entry = GTK_ENTRY (widget);
+  
   GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
-  gtk_entry_draw_focus (widget);
-  gtk_entry_queue_draw (GTK_ENTRY (widget));
+  gtk_entry_queue_draw (entry);
 
-  GTK_ENTRY (widget)->need_im_reset = TRUE;
-  gtk_im_context_focus_out (GTK_ENTRY (widget)->im_context);
+  entry->need_im_reset = TRUE;
+  gtk_im_context_focus_out (entry->im_context);
 
+  gtk_entry_check_cursor_blink (entry);
+  
   return FALSE;
 }
 
@@ -1667,14 +1650,11 @@ gtk_entry_real_set_position (GtkEditable *editable,
   if (position < 0 || position > entry->text_length)
     position = entry->text_length;
 
-  if (position != entry->current_pos)
+  if (position != entry->current_pos ||
+      position != entry->selection_bound)
     {
       gtk_entry_reset_im_context (entry);
-
-      entry->current_pos = entry->selection_bound = position;
-      gtk_entry_recompute (entry);
-
-      g_object_notify (G_OBJECT (entry), "text_position");
+      gtk_entry_set_positions (entry, position, position);
     }
 }
 
@@ -1698,12 +1678,11 @@ gtk_entry_set_selection_bounds (GtkEditable *editable,
   
   gtk_entry_reset_im_context (entry);
 
-  entry->selection_bound = MIN (start, entry->text_length);
-  entry->current_pos = MIN (end, entry->text_length);
+  gtk_entry_set_positions (entry,
+                          MIN (end, entry->text_length),
+                          MIN (start, entry->text_length));
 
   gtk_entry_update_primary_selection (entry);
-  
-  gtk_entry_recompute (entry);
 }
 
 static gboolean
@@ -1882,6 +1861,8 @@ gtk_entry_move_cursor (GtkEntry       *entry,
     gtk_editable_select_region (GTK_EDITABLE (entry), entry->selection_bound, new_pos);
   else
     gtk_editable_set_position (GTK_EDITABLE (entry), new_pos);
+  
+  gtk_entry_pend_cursor_blink (entry);
 }
 
 static void
@@ -1966,6 +1947,8 @@ gtk_entry_delete_from_cursor (GtkEntry       *entry,
       gtk_entry_delete_whitespace (entry);
       break;
     }
+  
+  gtk_entry_pend_cursor_blink (entry);
 }
 
 static void
@@ -2061,6 +2044,36 @@ gtk_entry_preedit_changed_cb (GtkIMContext *context,
 /* Internal functions
  */
 
+/* All changes to entry->current_pos and entry->selection_bound
+ * should go through this function.
+ */
+static void
+gtk_entry_set_positions (GtkEntry *entry,
+                        gint      current_pos,
+                        gint      selection_bound)
+{
+  gboolean changed = FALSE;
+  
+  if (current_pos != -1 &&
+      entry->current_pos != current_pos)
+    {
+      entry->current_pos = current_pos;
+      changed = TRUE;
+
+      g_object_notify (G_OBJECT (entry), "text_position");
+    }
+
+  if (selection_bound != -1 &&
+      entry->selection_bound != current_pos)
+    {
+      entry->selection_bound = selection_bound;
+      changed = TRUE;
+    }
+
+  if (changed)
+    gtk_entry_recompute (entry);
+}
+
 static void
 gtk_entry_reset_layout (GtkEntry *entry)
 {
@@ -2119,7 +2132,8 @@ static void
 gtk_entry_recompute (GtkEntry *entry)
 {
   gtk_entry_reset_layout (entry);
-
+  gtk_entry_check_cursor_blink (entry);
+  
   if (!entry->recompute_idle)
     {
       entry->recompute_idle = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 15, /* between resize and redraw */
@@ -2421,12 +2435,7 @@ gtk_entry_queue_draw (GtkEntry *entry)
   g_return_if_fail (GTK_IS_ENTRY (entry));
 
   if (GTK_WIDGET_REALIZED (entry))
-    {
-      GdkRectangle rect = { 0 };
-
-      gdk_window_get_size (entry->text_area, &rect.width, &rect.height);
-      gdk_window_invalidate_rect (entry->text_area, &rect, FALSE);
-    }
+    gdk_window_invalidate_rect (entry->text_area, NULL, FALSE);
 }
 
 static void
@@ -3483,3 +3492,137 @@ gtk_entry_drag_data_delete (GtkWidget      *widget,
   if (gtk_editable_get_selection_bounds (editable, &sel_start, &sel_end))
     gtk_editable_delete_text (editable, sel_start, sel_end);
 }
+
+/* We display the cursor when
+ *
+ *  - the selection is empty, AND
+ *  - the widget has focus
+ */
+
+#define CURSOR_ON_MULTIPLIER 0.66
+#define CURSOR_OFF_MULTIPLIER 0.34
+#define CURSOR_PEND_MULTIPLIER 1.0
+
+static gboolean
+cursor_blinks (GtkEntry *entry)
+{
+  GtkSettings *settings = gtk_settings_get_global ();
+  gboolean blink;
+
+  if (GTK_WIDGET_HAS_FOCUS (entry) &&
+      entry->selection_bound == entry->current_pos)
+    {
+      g_object_get (G_OBJECT (settings), "gtk-cursor-blink", &blink, NULL);
+      return blink;
+    }
+  else
+    return FALSE;
+}
+
+static gint
+get_cursor_time (GtkEntry *entry)
+{
+  GtkSettings *settings = gtk_settings_get_global ();
+  gint time;
+
+  g_object_get (G_OBJECT (settings), "gtk-cursor-blink-time", &time, NULL);
+
+  return time;
+}
+
+static void
+show_cursor (GtkEntry *entry)
+{
+  if (!entry->cursor_visible)
+    {
+      entry->cursor_visible = TRUE;
+
+      if (GTK_WIDGET_HAS_FOCUS (entry) && entry->selection_bound == entry->current_pos)
+       gtk_widget_queue_draw (GTK_WIDGET (entry));
+    }
+}
+
+static void
+hide_cursor (GtkEntry *entry)
+{
+  if (entry->cursor_visible)
+    {
+      entry->cursor_visible = FALSE;
+
+      if (GTK_WIDGET_HAS_FOCUS (entry) && entry->selection_bound == entry->current_pos)
+       gtk_widget_queue_draw (GTK_WIDGET (entry));
+    }
+}
+
+/*
+ * Blink!
+ */
+static gint
+blink_cb (gpointer data)
+{
+  GtkEntry *entry = GTK_ENTRY (data);
+  
+  g_assert (GTK_WIDGET_HAS_FOCUS (entry));
+  g_assert (entry->selection_bound == entry->current_pos);
+
+  if (entry->cursor_visible)
+    {
+      hide_cursor (entry);
+      entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_OFF_MULTIPLIER,
+                                             blink_cb,
+                                             entry);
+    }
+  else
+    {
+      show_cursor (entry);
+      entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER,
+                                             blink_cb,
+                                             entry);
+    }
+
+  /* Remove ourselves */
+  return FALSE;
+}
+
+static void
+gtk_entry_check_cursor_blink (GtkEntry *entry)
+{
+  if (cursor_blinks (entry))
+    {
+      if (!entry->blink_timeout)
+       {
+         entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER,
+                                                 blink_cb,
+                                                 entry);
+         show_cursor (entry);
+       }
+    }
+  else
+    {
+      if (entry->blink_timeout)  
+       { 
+         gtk_timeout_remove (entry->blink_timeout);
+         entry->blink_timeout = 0;
+       }
+      
+      entry->cursor_visible = TRUE;
+    }
+  
+}
+
+static void
+gtk_entry_pend_cursor_blink (GtkEntry *entry)
+{
+  if (cursor_blinks (entry))
+    {
+      if (entry->blink_timeout != 0)
+       gtk_timeout_remove (entry->blink_timeout);
+      
+      entry->blink_timeout = gtk_timeout_add (get_cursor_time (entry) * CURSOR_PEND_MULTIPLIER,
+                                             blink_cb,
+                                             entry);
+      show_cursor (entry);
+    }
+}
+                          
+
index a35e2be3cdaef633613bb061c74efb4f4b0aa974..efcf18d252fc006d297c513665c787d473424e1d 100644 (file)
@@ -80,9 +80,11 @@ struct _GtkEntry
   guint        has_frame : 1;
 
   guint        activates_default : 1;
+
+  guint        cursor_visible : 1;
   
   guint   button;
-  guint   timer;
+  guint   blink_timeout;
   guint   recompute_idle;
   gint    scroll_offset;
   gint    ascent;      /* font ascent, in pango units  */
index 214bdcc3052e962de016efeacd0189494ec2fc56..ee5c187dbef182fc83bb3f5d04a6bb31b08b711a 100644 (file)
@@ -21,7 +21,9 @@
 
 enum {
   PROP_0,
-  PROP_DOUBLE_CLICK_TIMEOUT
+  PROP_DOUBLE_CLICK_TIME,
+  PROP_CURSOR_BLINK,
+  PROP_CURSOR_BLINK_TIME,
 };
 
 
@@ -126,13 +128,29 @@ gtk_settings_class_init (GtkSettingsClass *class)
   g_assert (quark_property_id != 0);   /* special quarks from GObjectClass */
 
   result = settings_install_property_parser (class,
-                                             g_param_spec_int ("gtk-double-click-timeout",
-                                                               _("Double Click Timeout"),
-                                                               _("Maximum time allowed between two clicks for them to be considered a double click"),
+                                             g_param_spec_int ("gtk-double-click-time",
+                                                               _("Double Click Time"),
+                                                               _("Maximum time allowed between two clicks for them to be considered a double click (in milliseconds)"),
                                                                0, G_MAXINT, 250,
                                                                G_PARAM_READWRITE),
                                              NULL);
-  g_assert (result == PROP_DOUBLE_CLICK_TIMEOUT);
+  g_assert (result == PROP_DOUBLE_CLICK_TIME);
+  result = settings_install_property_parser (class,
+                                             g_param_spec_boolean ("gtk-cursor-blink",
+                                                                  _("Cursor Blink"),
+                                                                  _("Whether the cursor should blink"),
+                                                                  TRUE,
+                                                                  G_PARAM_READWRITE),
+                                            NULL);
+  g_assert (result == PROP_CURSOR_BLINK);
+  result = settings_install_property_parser (class,
+                                             g_param_spec_int ("gtk-cursor-blink-time",
+                                                               _("Cursor Blink Time"),
+                                                               _("Length of the cursor blink cycle, in milleseconds"),
+                                                               100, G_MAXINT, 1200,
+                                                               G_PARAM_READWRITE),
+                                             NULL);
+  g_assert (result == PROP_CURSOR_BLINK_TIME);
 }
 
 static void
@@ -201,7 +219,9 @@ gtk_settings_get_property (GObject     *object,
 {
   GtkSettings *settings = GTK_SETTINGS (object);
 
-  if (!gdk_setting_get (pspec->name, value))
+  if (gdk_setting_get (pspec->name, value))
+    g_param_value_validate (pspec, value);
+  else
     g_value_copy (settings->property_values + property_id - 1, value);
 }
 
@@ -221,7 +241,7 @@ gtk_settings_notify (GObject    *object,
 
   switch (property_id)
     {
-    case PROP_DOUBLE_CLICK_TIMEOUT:
+    case PROP_DOUBLE_CLICK_TIME:
       g_object_get (object, pspec->name, &double_click_time, NULL);
       gdk_set_double_click_time (double_click_time);
       break;
index 6641f75837abbaf10d2319f66d6157232f64a25c..7b63a6796e4f8a4bd5fe8047826f11a81a534092 100644 (file)
@@ -33,6 +33,7 @@
 #include "gtkmenu.h"
 #include "gtkmenuitem.h"
 #include "gtkseparatormenuitem.h"
+#include "gtksettings.h"
 #include "gtksignal.h"
 #include "gtktextdisplay.h"
 #include "gtktextview.h"
@@ -249,8 +250,8 @@ static gboolean gtk_text_view_end_selection_drag    (GtkTextView        *text_vi
 static void     gtk_text_view_start_selection_dnd   (GtkTextView        *text_view,
                                                      const GtkTextIter  *iter,
                                                      GdkEventMotion     *event);
-static void     gtk_text_view_start_cursor_blink    (GtkTextView        *text_view,
-                                                     gboolean            with_delay);
+static void     gtk_text_view_check_cursor_blink    (GtkTextView        *text_view);
+static void     gtk_text_view_pend_cursor_blink     (GtkTextView        *text_view);
 static void     gtk_text_view_stop_cursor_blink     (GtkTextView        *text_view);
 
 static void gtk_text_view_value_changed           (GtkAdjustment *adj,
@@ -1029,7 +1030,7 @@ gtk_text_view_set_buffer (GtkTextView   *text_view,
       text_view->first_para_pixels = 0;
 
       g_signal_connect_data (G_OBJECT (text_view->buffer), "mark_set",
-                             gtk_text_view_mark_set_handler, text_view,
+                             G_CALLBACK (gtk_text_view_mark_set_handler), text_view,
                              NULL, FALSE, FALSE);
     }
 
@@ -2018,11 +2019,7 @@ gtk_text_view_set_cursor_visible    (GtkTextView   *text_view,
           if (text_view->layout)
             {
               gtk_text_layout_set_cursor_visible (text_view->layout, setting);
-
-              if (setting)
-                gtk_text_view_start_cursor_blink (text_view, FALSE);
-              else
-                gtk_text_view_stop_cursor_blink (text_view);
+             gtk_text_view_check_cursor_blink (text_view);
             }
         }
     }
@@ -3126,7 +3123,7 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
   else
     retval = FALSE;
 
-  gtk_text_view_start_cursor_blink (text_view, TRUE);
+  gtk_text_view_pend_cursor_blink (text_view);
 
   return retval;
 }
@@ -3334,7 +3331,7 @@ gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
   if (text_view->cursor_visible && text_view->layout)
     {
       gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);
-      gtk_text_view_start_cursor_blink (text_view, FALSE);
+      gtk_text_view_check_cursor_blink (text_view);
     }
 
   text_view->need_im_reset = TRUE;
@@ -3354,7 +3351,7 @@ gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
   if (text_view->cursor_visible && text_view->layout)
     {
       gtk_text_layout_set_cursor_visible (text_view->layout, FALSE);
-      gtk_text_view_stop_cursor_blink (text_view);
+      gtk_text_view_check_cursor_blink (text_view);
     }
 
   text_view->need_im_reset = TRUE;
@@ -3565,27 +3562,29 @@ gtk_text_view_forall (GtkContainer *container,
     }
 }
 
-/* Note that CURSOR_ON_TIME is effectively added to PREBLINK_TIME
- * because blinking starts with the cursor turned on.
- */
-#define PREBLINK_TIME 300
-#define CURSOR_ON_TIME 800
-#define CURSOR_OFF_TIME 400
+#define CURSOR_ON_MULTIPLIER 0.66
+#define CURSOR_OFF_MULTIPLIER 0.34
+#define CURSOR_PEND_MULTIPLIER 1.0
 
-/*
- * preblink!
- */
+static gboolean
+cursor_blinks (GtkTextView *text_view)
+{
+  GtkSettings *settings = gtk_settings_get_global ();
+  gboolean blink;
+
+  g_object_get (G_OBJECT (settings), "gtk-cursor-blink", &blink, NULL);
+  return blink;
+}
 
 static gint
-preblink_cb (gpointer data)
+get_cursor_time (GtkTextView *text_view)
 {
-  GtkTextView *text_view = GTK_TEXT_VIEW (data);
+  GtkSettings *settings = gtk_settings_get_global ();
+  gint time;
 
-  text_view->preblink_timeout = 0;
-  gtk_text_view_start_cursor_blink (text_view, FALSE);
+  g_object_get (G_OBJECT (settings), "gtk-cursor-blink-time", &time, NULL);
 
-  /* Remove ourselves */
-  return FALSE;
+  return time;
 }
 
 /*
@@ -3605,11 +3604,11 @@ blink_cb (gpointer data)
   visible = gtk_text_layout_get_cursor_visible (text_view->layout);
 
   if (visible)
-    text_view->blink_timeout = gtk_timeout_add (CURSOR_OFF_TIME,
+    text_view->blink_timeout = gtk_timeout_add (get_cursor_time (text_view) * CURSOR_OFF_MULTIPLIER,
                                                 blink_cb,
                                                 text_view);
   else
-    text_view->blink_timeout = gtk_timeout_add (CURSOR_ON_TIME,
+    text_view->blink_timeout = gtk_timeout_add (get_cursor_time (text_view) * CURSOR_ON_MULTIPLIER,
                                                 blink_cb,
                                                 text_view);
   
@@ -3620,72 +3619,71 @@ blink_cb (gpointer data)
   return FALSE;
 }
 
+
+static void
+gtk_text_view_stop_cursor_blink (GtkTextView *text_view)
+{
+  if (text_view->blink_timeout)  
+    { 
+      gtk_timeout_remove (text_view->blink_timeout);
+      text_view->blink_timeout = 0;
+    }
+}
+
 static void
-gtk_text_view_start_cursor_blink(GtkTextView *text_view,
-                                 gboolean     with_delay)
+gtk_text_view_check_cursor_blink (GtkTextView *text_view)
 {
 #ifdef DEBUG_VALIDATION_AND_SCROLLING
   return;
 #endif
 
-  if (text_view->layout == NULL)
-    return;
-  
-  if (!text_view->cursor_visible)
-    return;
-
-  if (!GTK_WIDGET_HAS_FOCUS (text_view))
-    return;
-  
-  if (text_view->preblink_timeout != 0)
-    {
-      gtk_timeout_remove (text_view->preblink_timeout);
-      text_view->preblink_timeout = 0;
-    }
-  
-  if (with_delay)
-    {
-      if (text_view->blink_timeout != 0)
-        {
-          gtk_timeout_remove (text_view->blink_timeout);
-          text_view->blink_timeout = 0;
-        }
-      
-      gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);
-      
-      text_view->preblink_timeout = gtk_timeout_add (PREBLINK_TIME,
-                                                     preblink_cb,
-                                                     text_view);
+  if (text_view->layout != NULL &&
+      text_view->cursor_visible &&
+      GTK_WIDGET_HAS_FOCUS (text_view))
+    {
+      if (cursor_blinks (text_view))
+       {
+         if (text_view->blink_timeout == 0)
+           {
+             gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);
+             
+             text_view->blink_timeout = gtk_timeout_add (get_cursor_time (text_view) * CURSOR_OFF_MULTIPLIER,
+                                                         blink_cb,
+                                                         text_view);
+           }
+       }
+      else
+       gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);   
     }
   else
     {
-      if (text_view->blink_timeout == 0)
-        {
-          gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);
-          
-          text_view->blink_timeout = gtk_timeout_add (CURSOR_ON_TIME,
-                                                      blink_cb,
-                                                      text_view);
-        }
+      gtk_text_view_stop_cursor_blink (text_view);
     }
 }
 
 static void
-gtk_text_view_stop_cursor_blink (GtkTextView *text_view)
+gtk_text_view_pend_cursor_blink(GtkTextView *text_view)
 {
-  if (text_view->preblink_timeout)
+  if (text_view->layout != NULL &&
+      text_view->cursor_visible &&
+      GTK_WIDGET_HAS_FOCUS (text_view) &&
+      cursor_blinks (text_view))
     {
-      gtk_timeout_remove (text_view->preblink_timeout);
-      text_view->preblink_timeout = 0;
-    }
-
-  if (text_view->blink_timeout)  
-    { 
-      gtk_timeout_remove (text_view->blink_timeout);
-      text_view->blink_timeout = 0;
+      if (text_view->blink_timeout != 0)
+       {
+         gtk_timeout_remove (text_view->blink_timeout);
+         text_view->blink_timeout = 0;
+       }
+      
+      gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);
+      
+      text_view->blink_timeout = gtk_timeout_add (get_cursor_time (text_view) * CURSOR_PEND_MULTIPLIER,
+                                                 blink_cb,
+                                                 text_view);
     }
 }
 
+
 /*
  * Key binding handlers
  */
@@ -3724,7 +3722,7 @@ gtk_text_view_move_cursor (GtkTextView     *text_view,
   if (step == GTK_MOVEMENT_PAGES)
     {
       gtk_text_view_scroll_pages (text_view, count);
-      gtk_text_view_start_cursor_blink (text_view, TRUE);
+      gtk_text_view_pend_cursor_blink (text_view);
       return;
     }
 
@@ -3813,7 +3811,7 @@ gtk_text_view_move_cursor (GtkTextView     *text_view,
         }
     }
 
-  gtk_text_view_start_cursor_blink (text_view, TRUE);
+  gtk_text_view_pend_cursor_blink (text_view);
 }
 
 static void
@@ -4266,19 +4264,19 @@ gtk_text_view_ensure_layout (GtkTextView *text_view)
 
       g_signal_connect_data (G_OBJECT (text_view->layout),
                              "invalidated",
-                             invalidated_handler,
+                             G_CALLBACK (invalidated_handler),
                              text_view,
                              NULL, FALSE, FALSE);
 
       g_signal_connect_data (G_OBJECT (text_view->layout),
                              "changed",
-                             changed_handler,
+                             G_CALLBACK (changed_handler),
                              text_view,
                              NULL, FALSE, FALSE);
 
       g_signal_connect_data (G_OBJECT (text_view->layout),
                              "allocate_child",
-                             gtk_text_view_child_allocated,
+                             G_CALLBACK (gtk_text_view_child_allocated),
                              text_view,
                              NULL, FALSE, FALSE);
       
@@ -4286,7 +4284,7 @@ gtk_text_view_ensure_layout (GtkTextView *text_view)
         gtk_text_layout_set_buffer (text_view->layout, get_buffer (text_view));
 
       if ((GTK_WIDGET_HAS_FOCUS (text_view) && text_view->cursor_visible))
-        gtk_text_view_start_cursor_blink (text_view, FALSE);
+        gtk_text_view_pend_cursor_blink (text_view);
       else
         gtk_text_layout_set_cursor_visible (text_view->layout, FALSE);
 
@@ -6219,5 +6217,3 @@ gtk_text_view_move_visually (GtkTextView *text_view,
 
   return gtk_text_layout_move_iter_visually (text_view->layout, iter, count);
 }
-
-
index 9224657ca3cbcd88ad5a4ff48e51c4c37f1dc54a..3455655d9d6c96e75abd5fc9df367f8e62a418f3 100644 (file)
@@ -129,7 +129,6 @@ struct _GtkTextView
 
   GtkTextMark *dnd_mark;
   guint blink_timeout;
-  guint preblink_timeout;
 
   guint first_validate_idle;            /* Idle to revalidate onscreen portion, runs before resize */
   guint incremental_validate_idle;      /* Idle to revalidate offscreen portions, runs after redraw */